/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.formserver.viewmodel.webapi;

import static com.inspur.edp.formserver.viewmodel.common.ConvertUtils.toElement;
import static com.inspur.edp.formserver.viewmodel.common.ConvertUtils.toObject;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.inspur.edp.bef.bizentity.GspBizEntityElement;
import com.inspur.edp.bef.bizentity.GspBizEntityObject;
import com.inspur.edp.bef.bizentity.GspBusinessEntity;
import com.inspur.edp.bef.bizentity.json.element.BizElementDeserializer;
import com.inspur.edp.bef.bizentity.json.element.BizElementSerializer;
import com.inspur.edp.bef.bizentity.json.operation.BizMgrActionCollectionDeserializer;
import com.inspur.edp.bef.bizentity.operation.BizMgrAction;
import com.inspur.edp.bef.bizentity.operation.BizOperationCollection;
import com.inspur.edp.bef.bizentity.operation.collection.BizMgrActionCollection;
import com.inspur.edp.bef.bizentity.util.StringUtil;
import com.inspur.edp.cef.designtime.api.collection.GspFieldCollection;
import com.inspur.edp.cef.designtime.api.element.GspAssociation;
import com.inspur.edp.cef.designtime.api.json.element.GspAssociationSerializer;
import com.inspur.edp.das.commonmodel.IGspCommonElement;
import com.inspur.edp.das.commonmodel.IGspCommonModel;
import com.inspur.edp.das.commonmodel.IGspCommonObject;
import com.inspur.edp.das.commonmodel.collection.GspElementCollection;
import com.inspur.edp.das.commonmodel.entity.element.GspCommonAssociation;
import com.inspur.edp.das.commonmodel.entity.object.GspCommonObjectType;
import com.inspur.edp.formserver.viewmodel.GspViewModel;
import com.inspur.edp.formserver.viewmodel.GspViewModelElement;
import com.inspur.edp.formserver.viewmodel.GspViewObject;
import com.inspur.edp.formserver.viewmodel.action.ViewModelAction;
import com.inspur.edp.formserver.viewmodel.collection.VMActionCollection;
import com.inspur.edp.formserver.viewmodel.common.ConvertUtils;
import com.inspur.edp.formserver.viewmodel.common.InitVoUtil;
import com.inspur.edp.formserver.viewmodel.common.LinkBeUtils;
import com.inspur.edp.formserver.viewmodel.common.MappingType;
import com.inspur.edp.formserver.viewmodel.common.mapping.GspVoElementMapping;
import com.inspur.edp.formserver.viewmodel.common.mapping.GspVoElementSourceType;
import com.inspur.edp.formserver.viewmodel.common.mapping.GspVoObjectSourceType;
import com.inspur.edp.formserver.viewmodel.json.element.ViewElementDeserializer;
import com.inspur.edp.formserver.viewmodel.json.model.ViewModelDeserializer;
import com.inspur.edp.formserver.viewmodel.json.model.ViewModelSerializer;
import com.inspur.edp.formserver.viewmodel.json.operation.VmActionCollectionSerializer;
import com.inspur.edp.formserver.viewmodel.util.ViewModelUtils;
import com.inspur.edp.formserver.vmmanager.compcodebutton.CompButton;
import com.inspur.edp.formserver.vmmanager.exception.VmManagerException;
import com.inspur.edp.formserver.vmmanager.service.UpdateVariableWithUdtService;
import com.inspur.edp.formserver.vmmanager.service.UpdateVirtualVoElementWithUdtService;
import com.inspur.edp.formserver.vmmanager.service.VmManagerService;
import com.inspur.edp.formserver.vmmanager.service.WebControllerService;
import com.inspur.edp.formserver.vmmanager.util.CheckComUtil;
import com.inspur.edp.formserver.vmmanager.util.CheckInfoUtil;
import com.inspur.edp.formserver.vmmanager.util.SimplifyMetadataUtil;
import com.inspur.edp.lcm.metadata.api.entity.GspMetadata;
import com.inspur.edp.lcm.metadata.api.entity.GspProject;
import com.inspur.edp.lcm.metadata.api.service.FileService;
import com.inspur.edp.lcm.metadata.api.service.MetadataProjectService;
import com.inspur.edp.lcm.metadata.api.service.MetadataService;
import com.inspur.edp.lcm.metadata.api.service.RefCommonService;
import com.inspur.edp.web.help.metadata.HelpMetadataContent;
import io.iec.edp.caf.commons.exception.ExceptionLevel;
import io.iec.edp.caf.commons.utils.SpringBeanUtils;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.stream.Collectors;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import lombok.var;

@Path("")
@Produces(MediaType.APPLICATION_JSON)
public class ViewModelController {

  private final String EXCEPTIONCODE="vmWebApi";



  @Path("sysn")
  @PUT
  @Produces(MediaType.APPLICATION_JSON)
  public void saveAndSysn(String metadataInfo){
    ObjectMapper mapper=getViewModelMapper();
    MetadataService service= SpringBeanUtils.getBean(MetadataService.class);

    try {
      JsonNode node=mapper.readTree(metadataInfo);
      isMetadataCodeExist(node);
      String path=node.get("path").textValue();
      String metadataName=null;
      if(!CheckInfoUtil.checkNull(node.get("name"))){
        metadataName=node.get("name").textValue();
      }
      GspMetadata metadata=service.loadMetadata(metadataName,path);
      //生成构件元数据
      ArrayList list= VmManagerService.generateComponent(metadata,path,true);
      //构件代码模板
      VmManagerService.generateComponentCode(metadata,path,list);
      //保存元数据
      VmManagerService.saveMetadata(metadata,path);
    } catch (JsonProcessingException e) {
      throw new RuntimeException("元数据信息读取异常"+e);
    }
  }

  @Path("isHelpComp")
  @PUT
  @Produces(MediaType.APPLICATION_JSON)
  public boolean isHelpComp(String info){
    return true;
  }

  @Path("createVirtualVo")
  @PUT
  @Produces(MediaType.APPLICATION_JSON)
  public String creataVirtualVo(String info){
    ObjectMapper mapper=getViewModelMapper();
    try {
      JsonNode node=mapper.readTree(info);
      String metadataID=node.get("metadataID").textValue();
      String metadataName=null;
      if(!CheckInfoUtil.checkNull(node.get("metadataName"))){
        metadataName=node.get("metadataName").textValue();
      }
      String metadataCode=node.get("metadataCode").textValue();
      String metadataAssembly=node.get("metadataAssembly").textValue();
      GspViewModel vm= InitVoUtil
          .BuildVirtualVo(metadataID,metadataName,metadataCode,metadataAssembly);
      String vmJson=mapper.writeValueAsString(vm);
      return vmJson;
    } catch (JsonProcessingException e) {
      throw new RuntimeException("序列化异常"+e);
    }
  }

  @Path("convertBizEntity")
  @PUT
  @Produces(MediaType.APPLICATION_JSON)
  public String convertBizEntityToViewModel(String convertBeInfo) {
    ObjectMapper mapper=new ObjectMapper();
    try {
      JsonNode node= mapper.readTree(convertBeInfo);
      String bizEntityJson=node.get("bizEntityJson").textValue();
      String bePkgName=null;
      if(!CheckInfoUtil.checkNull(node.get("bePkgName"))){
        bePkgName=node.get("bePkgName").textValue();
      }

      String beId=node.get("beId").textValue();
      String voGeneratingAssembly=node.get("voGeneratingAssembly").textValue();
      return convertBizEntityToViewModel(bizEntityJson,bePkgName,beId,voGeneratingAssembly);
    } catch (JsonProcessingException e) {
      throw new RuntimeException(e);
    }

  }

  @Path("chooseUdt")
  @PUT
  @Produces(MediaType.APPLICATION_JSON)
  public String updateUdtElementWhenChooseUdt(String info) {
    ObjectMapper mapper=new ObjectMapper();
    try {
      JsonNode node= mapper.readTree(info);
      String refUdtId=node.get("refUdtId").textValue();
      String path=node.get("path").textValue();
      String beElementJson=node.get("udtElementJson").textValue();
      return UpdateVariableWithUdtService
          .getInstance().updateVariableWithRefUdt(refUdtId,path,beElementJson,true);
    } catch (JsonProcessingException e) {
      throw new RuntimeException(e);
    }

  }

  @Path("updateUdt")
  @PUT
  @Produces(MediaType.APPLICATION_JSON)
  public String updateUdtElementWhenLoading(String info) {
    ObjectMapper mapper=new ObjectMapper();
    try {
      JsonNode node= mapper.readTree(info);
      String refUdtId=node.get("refUdtId").textValue();
      String path=node.get("path").textValue();
      String beElementJson=node.get("udtElementJson").textValue();
      return UpdateVariableWithUdtService.getInstance().updateVariableWithRefUdt(refUdtId,path,beElementJson,false);
    } catch (JsonProcessingException e) {
      throw new RuntimeException(e);
    }

  }

  @Path("virtualVoChooseUdt")
  @PUT
  @Produces(MediaType.APPLICATION_JSON)
  public String updateVirtualVoUdtElementWhenChooseUdt(String info) {
    ObjectMapper mapper=new ObjectMapper();
    try {
      JsonNode node= mapper.readTree(info);
      String refUdtId=node.get("refUdtId").textValue();
      String path=node.get("path").textValue();
      String beElementJson=node.get("udtElementJson").textValue();
      return UpdateVirtualVoElementWithUdtService
          .getInstance().UpdateVariableWithRefUdt(refUdtId,path,beElementJson,true);
    } catch (JsonProcessingException e) {
      throw new RuntimeException(e);
    }

  }

  @Path("virtualVoUpdateUdt")
  @PUT
  @Produces(MediaType.APPLICATION_JSON)
  public String updateVirtualVoUdtElementWhenLoading(String info) {
    ObjectMapper mapper=new ObjectMapper();
    try {
      JsonNode node= mapper.readTree(info);
      String refUdtId=node.get("refUdtId").textValue();
      String path=node.get("path").textValue();
      String beElementJson=node.get("udtElementJson").textValue();
      return UpdateVirtualVoElementWithUdtService
          .getInstance().UpdateVariableWithRefUdt(refUdtId,path,beElementJson,false);
    } catch (JsonProcessingException e) {
      throw new RuntimeException(e);
    }

  }


  @Path("changeMainObj")
  @PUT
  @Produces(MediaType.APPLICATION_JSON)
  public String changeMainObj(String convertBeInfo) {
    ObjectMapper mapper=getViewModelMapper();
    try {
      JsonNode node= mapper.readTree(convertBeInfo);
      String newObjId=node.get("newObjId").textValue();
      String bePkgName=null;
      if(!CheckInfoUtil.checkNull(node.get("bePkgName"))){
        bePkgName=node.get("bePkgName").textValue();
      }

      String beId=node.get("beId").textValue();
      String voGeneratingAssembly=node.get("voGeneratingAssembly").textValue();
      GspBusinessEntity be=getBizEntity(null,bePkgName,beId);
      GspBizEntityObject bizObj= (GspBizEntityObject) be.findObjectById(newObjId);
      if (bizObj==null)
      {
        throw new VmManagerException("",EXCEPTIONCODE, "所选业务实体'{"+be.getName()+"}'中无选中的节点,业务实体id='{"+beId+"}', 节点id='{"+bizObj+"}'。",null,
            ExceptionLevel.Error,false);
      }
      // 处理子节点
      if (bizObj.getObjectType() == GspCommonObjectType.ChildObject)
      {
        bizObj.setObjectType(GspCommonObjectType.MainObject);
        bizObj.getKeys().clear();
        be.setMainObject(bizObj);
      }
      GspViewModel vm= ConvertUtils.convertToViewModel(be, bePkgName, beId, voGeneratingAssembly);
      String vmJson=mapper.writeValueAsString(vm);
      return vmJson;
    } catch (JsonProcessingException e) {
      throw new RuntimeException(e);
    }
  }


  @Path("getHelpVoTargetBeId")
  @PUT
  @Produces(MediaType.APPLICATION_JSON)
  public String getHelpVoTargetBeId(String convertBeInfo) {
    ObjectMapper mapper=new ObjectMapper();
    try {
      JsonNode node= mapper.readTree(convertBeInfo);
      String helperId=node.get("helperId").textValue();
      RefCommonService service=SpringBeanUtils.getBean(RefCommonService.class);
      HelpMetadataContent helpMetadataContent= (HelpMetadataContent) service.getRefMetadata(helperId).getContent();
      String voId=helpMetadataContent.getDataSource().getVoSourceId();
      GspViewModel helpVo= (GspViewModel) service.getRefMetadata(voId).getContent();
      if(helpVo==null){
        throw new RuntimeException("当前帮助"+helpMetadataContent.getName()+"无对应的vo元数据,helpId="+"帮助来源类型为:"+helpMetadataContent.getDataSource().getSourceType());
      }
      if (helpVo.getMapping() == null || helpVo.getMapping().getMapType() != MappingType.BizEntity)
      {
        throw new RuntimeException("当前帮助'"+helpMetadataContent.getName()+"'vo元数据非Be源。");
      }
      return "\""+helpVo.getMapping().getTargetMetadataId()+"\"";
    } catch (JsonProcessingException e) {
      throw new RuntimeException(e);
    }
  }



  @Path("convertBeElements")
  @PUT
  @Produces(MediaType.APPLICATION_JSON)
  public String convertBeElementIdsToVmElements(String convertEleInfo) {
    return WebControllerService.getInstance().convertBeElementIdsToVmElements(convertEleInfo,this::getBizEntity);
  }

  @Path("getBeAsso")
  @PUT
  @Produces(MediaType.APPLICATION_JSON)
  public String getBizAssoById(String info) {
    ObjectMapper mapper=new ObjectMapper();
    SimpleModule module =new SimpleModule();
    BizElementSerializer bizElementSerializer=new BizElementSerializer();
    GspAssociationSerializer associationDeserializer=new GspAssociationSerializer(bizElementSerializer);
    module.addSerializer(GspAssociation.class,associationDeserializer);
    mapper.registerModule(module);
    try {
      JsonNode node= mapper.readTree(info);
      String path = node.get("path").textValue();
      String voEleMappingJson = node.get("voEleMapping").textValue();
      String beAssoId = node.get("assoId").textValue();
      GspVoElementMapping voEleMapping = WebControllerService.getInstance().readVoEleMapping(voEleMappingJson);
      GspCommonAssociation bizAsso =WebControllerService.getInstance().getBizAsso(path, voEleMapping, beAssoId,this::getBizEntity);

      String bizAssoJson=mapper.writeValueAsString(bizAsso);
      return bizAssoJson;
    } catch (JsonProcessingException e) {
      throw new RuntimeException("GspAssociation序列化失败"+e);
    }
  }

  @Path("getVoAsso")
  @PUT
  @Produces(MediaType.APPLICATION_JSON)
  public String getVoAsso(String info) {
    ObjectMapper mapper=new ObjectMapper();
    try {
      JsonNode node= mapper.readTree(info);
      String path = node.get("path").textValue();
      String voEleMappingJson = node.get("voEleMapping").textValue();
      String beAssoJson = node.get("beAsso").textValue();
      String voAssoJson = node.get("voAsso").textValue();
      String refElementIdsJson = node.get("refElementIds").textValue();


      GspCommonAssociation beAsso = WebControllerService.getInstance().readAsso(beAssoJson,new BizElementDeserializer());
      GspCommonAssociation originVoAsso = WebControllerService.getInstance().readAsso(voAssoJson,new ViewElementDeserializer());
      var voEleMapping = WebControllerService.getInstance().readVoEleMapping(voEleMappingJson);
      var refElementIds=WebControllerService.getInstance().readIdList(refElementIdsJson);

      if (refElementIds.size() == 0)
      {
        throw new VmManagerException("",EXCEPTIONCODE, "当前未选中关联带出字段。",null,ExceptionLevel.Error,false);
      }

      GspFieldCollection bizRefElements = beAsso.getRefElementCollection();
      GspFieldCollection originVoRefElements = originVoAsso.getRefElementCollection();
      GspElementCollection refElements = new GspElementCollection(null);

      for (var refElementId : refElementIds)
      {
        IGspCommonElement voRefElement= (IGspCommonElement) originVoRefElements.stream().filter(item->item.getRefElementId().equals(refElementId)).findFirst().orElse(null);
        if (!( voRefElement instanceof GspViewModelElement))
        {
          IGspCommonElement  beRefElement= (IGspCommonElement) bizRefElements.stream().filter(item->item.getRefElementId().equals(refElementId)).findFirst().orElse(null);
          if (!(beRefElement instanceof GspBizEntityElement))
          {
            throw new VmManagerException("",EXCEPTIONCODE, "be关联中无refElementId='{"+refElementId+"}'的关联带出字段。",null,ExceptionLevel.Error,false);
          }
          else
          {
            refElements.add(toElement((IGspCommonElement) beRefElement,voEleMapping.getTargetMetadataPkgName(),voEleMapping.getTargetMetadataId(),voEleMapping.getSourceType()));
          }
        }
        else
        {
          refElements.add(voRefElement);
        }
      }
      return WebControllerService.getInstance().writeViewElementsJson(refElements);
    } catch (JsonProcessingException e) {
      throw new RuntimeException("GspAssociation序列化失败"+e);
    }

  }

  @Path("getVirtualVoAsso")
  @PUT
  @Produces(MediaType.APPLICATION_JSON)
  public String getVirtualVoAsso(String info) {
    return WebControllerService.getInstance().getVirtualVoAsso(info, this::getBizEntity);
  }

  @Path("convertActions")
  @PUT
  @Produces(MediaType.APPLICATION_JSON)
  public String convertBizActionsToVmActions(String convertActionInfo) {
    ObjectMapper mapper=new ObjectMapper();
    try {
      JsonNode node= mapper.readTree(convertActionInfo);
      String bizActionsJson = node.get("bizActionsJson").textValue();
      String bePkgName=null;
      if(!CheckInfoUtil.checkNull(node.get("bePkgName"))){
        bePkgName=node.get("bePkgName").textValue();
      }
      String beId = node.get("beId").textValue();
      return convertBizActionsToVmActions(bizActionsJson, bePkgName, beId);
    } catch (JsonProcessingException e) {
      throw new RuntimeException("GspAssociation序列化失败"+e);
    }
  }

  @Path("convertElements")
  @PUT
  @Produces(MediaType.APPLICATION_JSON)
  public String convertBizElementsToVmElements(String convertActionInfo) {
    ObjectMapper mapper=new ObjectMapper();
    try {
      JsonNode node= mapper.readTree(convertActionInfo);
      String bizElementsJson = node.get("bizElementsJson").textValue();
      String bePkgName=null;
      if(!CheckInfoUtil.checkNull(node.get("bePkgName"))){
        bePkgName=node.get("bePkgName").textValue();
      }
      String beId = node.get("beId").textValue();
      return convertBizActionsToVmActions(bizElementsJson, bePkgName, beId);
    } catch (JsonProcessingException e) {
      throw new RuntimeException("GspAssociation序列化失败"+e);
    }
  }

  @Path("getbizObject/{beid}/{objid}")
  @GET
  @Produces(MediaType.APPLICATION_JSON)
  public String getBizObject(@PathParam("beid") String beid,@PathParam("objid") String objid,@QueryParam("path") String path,@QueryParam("bePkgName") String bePkgName) {
    GspBusinessEntity be=getBizEntity(path,bePkgName,beid);
    return WebControllerService.getInstance().getBizObject(be, objid);
  }

  @Path("addObjects")
  @GET
  @Produces(MediaType.APPLICATION_JSON)
  public String addBizObjects(String convertActionInfo) {
    ObjectMapper mapper=new ObjectMapper();
    SimpleModule module =new SimpleModule();
    module.addSerializer(IGspCommonModel.class,new ViewModelSerializer());
    module.addDeserializer(IGspCommonModel.class,new ViewModelDeserializer());
    mapper.registerModule(module);
    try {
      JsonNode node= mapper.readTree(convertActionInfo);
      String vmJson = node.get("vmJson").textValue();
      String bizObjIdsJson = node.get("bizObjIds").textValue();
      String path = node.get("path").textValue();
      String bePkgName=null;
      if(!CheckInfoUtil.checkNull(node.get("bePkgName"))){
        bePkgName=node.get("bePkgName").textValue();
      }
      String beId = node.get("beId").textValue();

      List<String> bizObjIds = WebControllerService.getInstance().readIdList(bizObjIdsJson);

      GspBusinessEntity be = getBizEntity(path, bePkgName, beId);
      GspViewModel vm =mapper.readValue(vmJson,GspViewModel.class);
      List<String> allBizObjIds = be.getAllObjectList().stream().map(item -> item.getID()).collect(
          Collectors.toList());//.Select(item => item.ID).ToList();
      List<String> vmObjMappingIds = vm.getAllObjectList().stream().map(item -> ((GspViewObject)item).getMapping().getTargetObjId()).collect(
          Collectors.toList());//.Select(item => ((GspViewObject)item).Mapping.TargetObjId).ToList();

      List<String>  newVmMappingObjIds = bizObjIds.stream().filter(item ->!vmObjMappingIds.contains(item)).collect(Collectors.toList());//.Where(item => !vmObjMappingIds.Contains(item)).ToList();
      if (newVmMappingObjIds.size()== 0)
      {
        return mapper.writeValueAsString(vm);
      }

      // 删除未选中的be对象
      var redundantBizObjIds = allBizObjIds.stream().filter(item ->!vmObjMappingIds.contains(item)).collect(Collectors.toList());//.Where(item => !bizObjIds.Contains(item)).ToList();
      removeRedundantBizObj(be, redundantBizObjIds);

      // 添加新增的be对象
      addNewBizObject(vm, be, newVmMappingObjIds, vmObjMappingIds);
      return mapper.writeValueAsString(vm);
    } catch (JsonProcessingException e) {
      throw new RuntimeException("GspAssociation序列化失败"+e);
    }
  }

  private void addNewBizObject(GspViewModel vm, GspBusinessEntity be,List<String>  newVmMappingObjIds,
      List<String> vmObjMappingIds) {
    if (newVmMappingObjIds.size() != 0)
    {
      List<String> ids = newVmMappingObjIds;
      for(String id :ids){
        IGspCommonObject bizObj=getObjectById(be,id);
        String parentObjId=bizObj.getParentObject().getID();
        if(vmObjMappingIds.contains(parentObjId)){
          IGspCommonObject parentObj=getMappedObjectById(vm,parentObjId);
          if(parentObj==null)
            parentObj.getContainChildObjects().add(
                toObject(bizObj,vm.getMapping().getTargetMetadataPkgName(),vm.getMapping().getTargetMetadataId(),parentObj.getIDElement().getID(),GspVoObjectSourceType.BeObject));
        }
      }
    }
  }

  private IGspCommonObject getObjectById(IGspCommonModel cm, String id)
  {
    return cm.getAllObjectList().stream().filter((item)->item.getID().equals(id)).findFirst().orElse(null);//;.Find(obj => obj.ID == id);
  }

  private IGspCommonObject getMappedObjectById(GspViewModel vm, String id)
  {
    return vm.getAllObjectList().stream().filter((item)->((GspViewModel)item).getMapping().getTargetObjId().equals(id)).findFirst().orElse(null);//.Find(obj => ((GspViewObject)obj).Mapping.TargetObjId == id);
  }
  private void removeRedundantBizObj(GspBusinessEntity be, List<String> redundantBizObjIds) {
    if (redundantBizObjIds.size() != 0)
    {
      for (String id : redundantBizObjIds)
      {
        IGspCommonObject childObj = getObjectById(be, id);
        if(childObj==null)
          continue;
        childObj.getParentObject().getContainChildObjects().remove(childObj);
      }
    }
  }

  @Path("addObject")
  @PUT
  @Produces(MediaType.APPLICATION_JSON)
  public String addBizObject(String addObjInfo) {
    return WebControllerService.getInstance().addBizObject(addObjInfo,this::getBizEntity);
  }

  @Path("batchSimplification")
  @PUT
  @Produces(MediaType.APPLICATION_JSON)
  public void SimplifyMetadata() {
    SimplifyMetadataUtil util = new SimplifyMetadataUtil();
    util.Simplify();
  }



  private String convertBizActionsToVmActions(String bizActionsJson, String bePkgName,
      String beId) {
    VMActionCollection vmActions = new VMActionCollection();
    BizMgrActionCollection bizMgrActions = readBizMgrActions(bizActionsJson);
    if (bizMgrActions.getCount() > 0)
    {
      bizMgrActions.forEach(mgrAction -> { var vmAction = ConvertUtils.toMappedAction((BizMgrAction)mgrAction, beId, bePkgName);vmActions.add(vmAction);
      });
    }
    return writeViewObjectsJson(vmActions);
  }

  private String writeViewObjectsJson(VMActionCollection vmActions) {
    ObjectMapper mapper=new ObjectMapper();
    SimpleModule module =new SimpleModule();
    module.addSerializer(VMActionCollection.class,new VmActionCollectionSerializer());
    mapper.registerModule(module);
    try {
      String vmActionsJson=mapper.writeValueAsString(vmActions);
      return vmActionsJson;
    } catch (JsonProcessingException e) {
      throw new RuntimeException("VMActionCollection序列化失败"+e);
    }
  }

  private BizMgrActionCollection readBizMgrActions(String bizActionsJson) {
    ObjectMapper mapper=new ObjectMapper();
    SimpleModule module =new SimpleModule();
    module.addDeserializer(BizOperationCollection.class,new BizMgrActionCollectionDeserializer());
    mapper.registerModule(module);
    try {
      BizMgrActionCollection bizOperations= (BizMgrActionCollection) mapper.readValue(bizActionsJson,BizOperationCollection.class);
      return bizOperations;
    } catch (JsonProcessingException e) {
      throw new RuntimeException("BizMgrActionCollection反序列化失败"+e);
    }
  }

  public static GspElementCollection convertPartialElementsToVoElements(IGspCommonObject co, List<String> eleIdList, String pkgName, String metaId, GspVoElementSourceType sourceType )
  {
    GspElementCollection voElements = new GspElementCollection(null);
    if (eleIdList != null && eleIdList.size() > 0)
    {
      for (String eleId : eleIdList)
      {
        GspBizEntityElement bizElement = (GspBizEntityElement) co.findElement(eleId);
        GspViewModelElement voElement = toElement(bizElement, pkgName, metaId, sourceType);
        voElement.getMapping().setTargetObjectId(co.getID());
        voElements.add(voElement);
      }
    }
    return voElements;
  }

  private ObjectMapper getViewModelMapper(){
    ObjectMapper mapper=new ObjectMapper();
    SimpleModule module =new SimpleModule();
    module.addSerializer(IGspCommonModel.class,new ViewModelSerializer());
    module.addDeserializer(IGspCommonModel.class,new ViewModelDeserializer());
    mapper.registerModule(module);
    return  mapper;
  }
  private String convertBizEntityToViewModel(String bizEntityJson, String bePkgName, String beId,
      String voGeneratingAssembly) {
    GspBusinessEntity be = null;
    try {
      be = new ObjectMapper().readValue(bizEntityJson, GspBusinessEntity.class);
      GspViewModel vm = ConvertUtils.convertToViewModel(be, bePkgName, beId, voGeneratingAssembly);
//       联动vo的关联带出字段枚举信息
            LinkBeUtils linkBeUtils = new LinkBeUtils();
            linkBeUtils.linkBeRefElements(vm);

      return new ObjectMapper().writeValueAsString(vm);
    } catch (JsonProcessingException e) {
      throw new RuntimeException("元数据序列化失败", e);
    }
  }
  private GspBusinessEntity getBizEntity(String path, String bePkgName, String beId)
  {

    if (ViewModelUtils.checkNull(beId))
    {
      throw new VmManagerException("",EXCEPTIONCODE, "待获取的业务实体元数据id不可为空。",null, ExceptionLevel.Error,false);
    }
    GspMetadata metadata =SpringBeanUtils.getBean(RefCommonService.class).getRefMetadata(beId);
    if (!(metadata.getContent() instanceof GspBusinessEntity))
    {
      throw new VmManagerException("",EXCEPTIONCODE, String.format("无法加载id='%1$s'的业务实体元数据。", beId),null,ExceptionLevel.Error,false);
    }
    return (GspBusinessEntity) metadata.getContent();
  }

  /**
   * 获取VO动作构件代码路径
   * @param info
   * @return
   */
  @Path("VOComponentCodePath")
  @PUT
  @Produces(MediaType.APPLICATION_JSON)
  public String getVOComponentCodePath(JsonNode info) {
    String id = info.get("metadataId").textValue();
    String projectpath = info.get("metadataPath").textValue();
    String type = info.get("actionType").textValue();
    String action = info.get("actionCode").textValue();
    ArrayList<String> actionList = new ArrayList<>();
    actionList.add(action);
    GspMetadata metadata = SpringBeanUtils.getBean(MetadataService.class).loadMetadataByMetadataId(id, projectpath);
    GspViewModel vo = (GspViewModel) metadata.getContent();
    String relativePath = metadata.getRelativePath();

    GspProject metadataProj = SpringBeanUtils.getBean(MetadataService.class).getGspProjectInfo(relativePath);
    String compAssemblyName = metadataProj.getProjectNameSpace();

    CompButton button = new CompButton();
    String filePath =button.getCompPath(vo,type,relativePath,actionList,compAssemblyName);
    filePath.replaceAll("\\\\", Matcher.quoteReplacement(File.separator));
    filePath.replaceAll("/", Matcher.quoteReplacement(File.separator));

    return filePath;
  }

  /**
   * 获取VO动作构件代码
   * @param info
   * @return
   */
  @Path("VOComponentCode")
  @PUT
  @Produces(MediaType.APPLICATION_JSON)
  public String getVOComponentCode(JsonNode info) {
    String id = info.get("metadataId").textValue();
    String projectpath = info.get("metadataPath").textValue();
    String type = info.get("actionType").textValue();
    String action = info.get("actionCode").textValue();
    ArrayList<String> actionList = new ArrayList<>();
    actionList.add(action);
    GspMetadata metadata = SpringBeanUtils.getBean(MetadataService.class).loadMetadataByMetadataId(id, projectpath);
    GspViewModel vo = (GspViewModel) metadata.getContent();
    String relativePath = metadata.getRelativePath();
    GspProject metadataProj = SpringBeanUtils.getBean(MetadataService.class).getGspProjectInfo(relativePath);
    String compAssemblyName = metadataProj.getProjectNameSpace();

    CompButton button = new CompButton();
    String code =button.getCompCode(vo,type,relativePath,actionList,compAssemblyName);

    return code;
  }

  /**
   * 判断当前元数据是否在当前BO内
   * @param info
   * @return
   */
  @Path("isMetadataExist")
  @PUT
  @Produces(MediaType.APPLICATION_JSON)
  public boolean isMetadataExist(JsonNode info) {
    if(StringUtil.checkNull(info)) {
      return false;
    }
    String path = info.get("path").textValue();
    String metadataFileName = info.get("metadataFileName").textValue();
    MetadataService service = SpringBeanUtils.getBean(com.inspur.edp.lcm.metadata.api.service.MetadataService.class);
    return service.isMetadataExist(path, metadataFileName);
  }

  private void isMetadataCodeExist(JsonNode info) {
    if(StringUtil.checkNull(info)) {
      return;
    }
    String metadataName = info.get("name").textValue();
    String projectPath = info.get("path").textValue();

    GspMetadata metadata = SpringBeanUtils.getBean(MetadataService.class).loadMetadata(metadataName, projectPath);
    GspViewModel vo = (GspViewModel) metadata.getContent();
    List<CheckComUtil> checkInfo = new ArrayList<>();
    CompButton button = new CompButton();
    button.getNewActions(vo,checkInfo);
    String relativePath = metadata.getRelativePath();
    MetadataProjectService service = SpringBeanUtils.getBean(MetadataProjectService.class);
    String compModulePath = service.getJavaCompProjectPath(relativePath);
    GspProject metadataProj = SpringBeanUtils.getBean(MetadataService.class).getGspProjectInfo(relativePath);
    String compAssemblyName = metadataProj.getProjectNameSpace();
    if(checkInfo.size()<=0){
      return;
    }

    for(CheckComUtil checkComUtil : checkInfo) {
      ArrayList<String> actionList = new ArrayList<>();
      actionList.add(checkComUtil.getAction());
      String filePath = button.getFilePath(vo, checkComUtil,compModulePath,compAssemblyName);
      filePath.replaceAll("\\\\", Matcher.quoteReplacement(File.separator));
      filePath.replaceAll("/", Matcher.quoteReplacement(File.separator));
      FileService fsService = SpringBeanUtils.getBean(FileService.class);
      if (fsService.isFileExist(filePath)) {
        String fileName = "";
        if(!"VarDeterminations".equals(checkComUtil.getType())){
          fileName = checkComUtil.getAction()+"VOAction.java";
        }else {
          fileName = vo.getName()+"Variable"+checkComUtil.getAction()+"VODtm.java";
        }
        throw new RuntimeException("已存在名为"+fileName+"的构件代码文件，请修改编号为"+checkComUtil.getAction()+"、名称为"+checkComUtil.getActionName()+"的"+checkComUtil.getCheckInfo()+"的编号，再执行保存操作。"+"\r\n代码路径："+filePath);
      }
    }
  }

}
